﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using QueuesData;
using QueuesClients;
using System.Data;
using System.Data.SqlClient;

namespace QueuesAdmin {
    /// <summary>
    /// Interaction logic for AdminWindow.xaml
    /// </summary>
    public partial class AdminWindow : Window {
        private QueuesDBEntities context;
        private ClientsManager clientsMan;
        private List<ComboBox> combos = new List<ComboBox>(5);

        public AdminWindow() {
            InitializeComponent();
            clientsMan = new ClientsManager();
            context = new QueuesDBEntities();
            var contents = context.Subjects.ToList();

            #region Assuntos do dia
            //allow the null selection
            contents.Insert(0, new Subject() { Id = -1, Name = "", Description = "" });
            this.DataContext = contents;

            combos.Add(comboA);
            combos.Add(comboB);
            combos.Add(comboC);
            combos.Add(comboD);

            #endregion

            #region Relatórios

            DateFrom.SelectedDate = DateTime.Now;
            DateTo.SelectedDate = DateTime.Now;

            #endregion


        }

        private async void ButtonSave_Click(object sender, RoutedEventArgs e) {
            if (ValidateSelections()) {

                var result = MessageBox.Show("Deseja selecionar estes assuntos e reiniciar a numeração?",
                    "Confirmar", MessageBoxButton.YesNo, MessageBoxImage.Question);

                if (result != MessageBoxResult.Yes) {
                    return;
                }

                using (var db = new QueuesDBEntities()) {
                    var previousSubjects = db.CurrentSubjects.ToList();

                    var session = new WorkSession();
                    session.CreationTime = DateTime.Now;
                    db.WorkSessions.Add(session);
                    db.SaveChanges();
                    db.Entry(session).Reload();

                    foreach (var c in combos) {
                        if (c.SelectedIndex > 0) {
                            var wSub = new WorkSessionSubject();
                            wSub.WorkSessionId = session.Id;
                            wSub.SubjectId = (int) c.SelectedValue;
                            wSub.SubjectMnemonic = c.Tag.ToString();
                            db.WorkSessionSubjects.Add(wSub);
                        }
                    }
                    db.SaveChanges();

                    info.Foreground = Brushes.DarkGreen;
                    info.Content = "Assuntos atualizados com sucesso";

                    await clientsMan.ReinitializeAllClientsAsync();
                }
            }
        }

        private bool ValidateSelections() {
            var selected = from c in combos
                           where c.SelectedIndex > 0
                           select c.SelectedIndex;

            info.Visibility = System.Windows.Visibility.Visible;
            if (selected.Count() == 0) {
                info.Foreground = Brushes.DarkRed;
                info.Content = "Deve selecionar pelo menos um assunto";
                return false;
            }

            if (selected.Distinct().Count() < selected.Count()) {
                info.Foreground = Brushes.DarkRed;
                info.Content = "Não pode haver assunto repetidos";
                return false;
            }

            return true;
        }

        private bool ValidateSubjects() {
            foreach (var item in subjectDataGrid.Items) {
                var sub = item as Subject;
                if (sub != null && (sub.Name.Length < 3 || sub.Name.Length < 3)) {
                    SetInfo("O nome do assunto deve ter entre 3 e 10 caracteres");
                    return false;
                }
            }
            return true;
        }

        private void FillComboBoxes(object sender, RoutedEventArgs e) {
            using (var db = new QueuesDBEntities()) {
                foreach (var c in combos) {
                    var tag = c.Tag.ToString();
                    var sub = db.CurrentSubjects.AsQueryable().Where(s => s.Mnemonic == tag).FirstOrDefault();
                    c.SelectedValue = sub != null ? sub.Id : -1;
                }
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e) {
            System.Windows.Data.CollectionViewSource subjectViewSource = ((System.Windows.Data.CollectionViewSource) (this.FindResource("subjectViewSource")));
            // Load data by setting the CollectionViewSource.Source property:
            subjectViewSource.Source = context.Subjects.Local;
        }

        public void SetInfo(string message) {
            LabelInfo.Content = message;
        }

        private void SaveButtonClick(object sender, RoutedEventArgs e) {
            var a = subjectDataGrid.Items;
            try {
                context.SaveChanges();
                SetInfo("As alterações foram guardadas");

            }
            catch (Exception) {
                SetInfo("Ocorreu um erro. Os dados não foram alterados");
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
            context.Dispose();
        }

        private void SubjectDataGrid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) {
            LabelInfo.Content = "";
        }

        private void ClearInfo(object sender, SelectionChangedEventArgs e) {
            if (info != null) {
                info.Content = "";
            }

            if (LabelInfoAcess != null) {
                LabelInfoAcess.Content = "";                
            }
        }

        private void BtnCancel_Click(object sender, RoutedEventArgs e) {
            Close();
        }

        private void ShowGrid(object sender, RoutedEventArgs e) {
            var start = DateFrom.SelectedDate ?? DateTime.Now;
            var end = DateTo.SelectedDate ?? DateTime.Now;
            int duration = 0;
            if (ChkFilterDuration.IsChecked ?? false) {
                int.TryParse(TxtDuration.Text, out duration);
            }

            SqlConnection conn;
            using (var db = new QueuesDBEntities()) {
                conn = new SqlConnection(db.Database.Connection.ConnectionString);
            }

            conn.Open();
            var command = conn.CreateCommand();

            command.CommandText = @"SELECT Subjects.Name AS Assunto, COUNT(*) AS ""Total de senhas""
                                    FROM   Attendings INNER JOIN
                                           Tickets ON Attendings.TicketId = Tickets.Id INNER JOIN
                                           Subjects ON Tickets.SubjectId = Subjects.Id
                                    WHERE  (Attendings.StartTime >= @start)
                                    AND (Attendings.StartTime < @end)
                                    AND (DATEDIFF(second, Attendings.StartTime, Attendings.EndTime) >= @duration)
                                    GROUP BY Subjects.Name";

            command.Parameters.AddWithValue("@start", start.Date);
            command.Parameters.AddWithValue("@end", end.Date.AddDays(1));
            command.Parameters.AddWithValue("@duration", duration);
            var reader = command.ExecuteReader();
            int total = 0;
            while (reader.Read()) {
                total += reader.GetInt32(1);
            }
            reader.Close();
            DataGridTotals.DataContext = command.ExecuteReader();

            TxtTotal.Text = "Total: " + total.ToString();
        }

        private void ToggleTxtDurationEnabled(object sender, RoutedEventArgs e) {
            TxtDuration.IsEnabled = ChkFilterDuration.IsChecked ?? false;
        }

        private async void UpdateSoundOptions(object sender, RoutedEventArgs e) {
            bool useAlert = false;
            bool useVoice = false;
            var item = comboSoundOptions.SelectedItem as ComboBoxItem;

            if (item != null) {
                switch (item.Tag.ToString()) {
                    case "1":
                        useAlert = true;
                        break;
                    case "2":
                        useVoice = true;
                        break;
                    case "3":
                        useAlert = true;
                        useVoice = true;
                        break;
                    default:
                        break;
                }
            }

            foreach (var p in clientsMan.InfoPanels) {
                await p.SetSoundOptionsAsync(useAlert, useVoice);
            }

            LabelInfoAcess.Foreground = Brushes.DarkGreen;
            LabelInfoAcess.Content = "Os painéis informativos foram atualizados";
        }
    }

    internal class SubjectNameRule : ValidationRule {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) {
            var name = value as string;

            if (name == null) {
                return new ValidationResult(false, "O nome não pode ser nulo");
            }

            if (name.Length < 3 || name.Length > 10) {
                return new ValidationResult(false, "O nome do assunto deve ter entre 3 e 10 caracteres");
            }

            return ValidationResult.ValidResult;
        }
    }
}
